iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
自我挑戰組

C# 從入門到WebApi系列 第 9

[Day9] Lambda 表示式(匿名委派) 與 LINQ

  • 分享至 

  • xImage
  •  

λ(lambda)運算式

λ(lambda)運算式其實是一種委派
不過他是匿名的委派
主要有兩種形式

  • 以運算式作為主體的運算式 Lambda
  • 以陳述式區塊作為主體的陳述式 Lambda

我們使用 Lambda 宣告運算子( => )來分隔參數清單和主體
也就是=>左邊的是傳入參數
=>右邊的是你的方法

以運算式作為主體的運算式 Lambda

委派的邏輯只需要一行就可以寫完
不需要寫 return 關鍵字
也不需要用大括號把邏輯包起來
無參數的lambda表示式 我們用小括弧來表示

Action action = () => Console.ReadLine();

帶單一參數的lambda表示式 我們可以省略括號

Func<int,int> square = x => x * x;

帶2個以上參數的lambda表示式 我們使用小括號將參數包起來

Func<int, int, bool> testForEquality = (x, y) => x == y;

有時候編譯器無法推斷輸入類型 可以明確指定類型

Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;

以陳述式作為主體的運算式 Lambda

陳述式 Lambda 看起來就像是運算式 Lambda,不同之處在於,陳述式會包含於大括號內

Action<string> greet = name =>
{
    string greeting = $"Hello {name}!";
    Console.WriteLine(greeting);
};
greet("World");

關於LINQ(讀作link)

Language Integrated Query (LINQ) 是一組以直接將查詢功能整合至 C# 語言為基礎之技術的名稱。
透過使用LINQ,您就可以利用最少的程式碼,針對資料來源執行篩選、排序及分組作業
使用相同的基本查詢運算式模式,來查詢並轉換 SQL 資料庫、ADO .NET 資料集、XML 文件以及 .NET 集合中的資料

因為在後面WebApi的部分會大量使用
剛好Linq經常會搭配lambda表示式一起使用

SQL 基本語法

在開始使用linq之前
我怕有些人以前沒有接觸過資料庫
簡單提一點點SQL(Structured Query Language:結構化查詢語言)
簡單來說就是用來操作資料庫的語法

Select * from DataBase Where price>100

假設我們有一張表

id name price
1 蘋果 25
2 香蕉 15
3 芒果 60
4 哈密瓜 120
5 榴槤 150

今天歐郎發大財
想到菜市場甲追勾
因為她很有錢
所以只挑100元以上的水果
我們可以用

Select * from DataBase Where price>100

上面的SQL大意是
從DataBase這張表取出所有price>100的欄位
*代表所有欄位

用上面的語法查詢就會得到

id name price
4 哈密瓜 120
5 榴槤 150

若是我們想要取得價格等於25的水果名字

Select name from DataBase Where price=25

SQL的等號就是一個=

name
蘋果

使用linq

要使用Linq前記得引用命名空間

using System.Linq;

我們建立水果類別
Fruit.cs

    public class Fruit
    {
        public int ID { get; set; }
        public string Name  { get; set; }
        public int Price { get; set; }
    }

建立一個水果列表
裡面有很多水果(跟上面表一樣)

        List<Fruit> fruitList = new List<Fruit>
        {
            new Fruit{ID=1,Name="蘋果",Price=25},
            new Fruit{ID=2,Name="香蕉",Price=15},
            new Fruit{ID=3,Name="芒果",Price=60},
            new Fruit{ID=4,Name="哈密瓜",Price=120},
            new Fruit{ID=5,Name="榴槤",Price=150}
        };

今天歐郎想要問他哥哥要不吃哈密瓜
所以決定找哈密瓜的價錢
對於用linq 操作的回傳型別我會使用var
因為常常會忘記接回來的是甚麼

var price = from fruit in fruitList where fruit.Name == "哈密瓜" select fruit.Price;

這邊的等於就是你我熟悉的C#==(都0202年還有人==不加空格)
看起來像不像倒裝的SQL語法
這邊的fruit其實是個自訂的變數
代表fruitList這個集合內的元素

回傳類型是IEnumable<int>
大概就是比較基礎的List(先這樣理解吧)
想知道是甚麼可以看(IEnumerable 介面)[https://docs.microsoft.com/zh-tw/dotnet/api/system.collections.ienumerable?view=netcore-3.1]

因為會搜尋所有符合條件的物件
所以回傳一個集合

我們用lambda改寫

fruitList.Where(x => x.Name == "哈密瓜").Select(x => x.Price);

其中x是自訂變數
大概跟上面的fruit差不多
我們在使用lambda時變數通常比較少取名得太複雜(除非lambda裡面又包lambda)

今天歐郎想要第一筆價錢大於50的水果
我們可以使用First

var fruit = fruitList.First(x => x.Price > 50);\
// fruit = {ID=3,Name="芒果",Price=60}

但是我不推薦
因為當沒有東西符合條件時會報錯
推薦使用FirstOrDefault
當找不到符合值時他會返回預設值

var fruit = fruitList.FirstOrDefault(x => x.Price > 200);
// fruit = null

上一篇
[Day8] 委派(delegate),Action<T> ,與Func<T,TResult>
下一篇
[Day10] 多執行緒與同步問題
系列文
C# 從入門到WebApi30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言